package mx.com.crowdgine.app;

import javax.media.opengl.GLAutoDrawable;

import com.jme3.input.InputManager;
import com.jme3.input.JoyInput;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.awt.AwtKeyInput;
import com.jme3.input.awt.AwtMouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseAxisTrigger;
import com.jme3.input.controls.MouseButtonTrigger;

import mx.com.crowdgine.display.jogl.JoglRenderer;

public class JoglApplication extends JoglRenderer{
	
	//Input manager
	protected InputManager inputManager;
	protected MouseInput mouseInput;
    protected KeyInput keyInput;
    protected JoyInput joyInput;
	
    private ActionListener actionListener = new ActionListener(){
        public void onAction(String name, boolean pressed){
            updateActionListener(name, pressed);
        }
    };
    
    public AnalogListener analogListener = new AnalogListener() {
        public void onAnalog(String name, float value) {
        	updateAnalogListener(name, value);
        }
    };
    
	public JoglApplication(){
		super();
	}
	
	public JoglApplication(String frameName,int width, int height){
		super(frameName, width,height);
	}
	
	public void initialize(){
		;
	}
	
	protected void updateActionListener(String name, boolean pressed){
		if(name=="Quit"){
			System.exit(0);
		}
		
		if(name == "ScriptedCamera"){
			setCamera(2);
		}
		
		if(name == "JOGLCamera"){
			setCamera(1);
		}
	}
	
	protected void updateAnalogListener(String name, float value){
		//TODO: Not sure if this should be implemented here :(
		if(name=="MouseLeft"){
			;
		}
		if(name=="MouseRight"){
			;
		}
		if(name=="MouseUp"){
			;
		}
		if(name=="MouseDown"){
			;
		}
	}
	
	/**
	 * This method is used to initialize object that need a drawable instance,
	 * such as particle systems and other opencl interactions.
	 * @param drawable This instance of drawable is automatically created.
	 */
	public void init(GLAutoDrawable drawable){
		super.init(drawable);
		initInput();
	}
	
	/**
	 * Initializes the necessary elements for the input to work.
	 */
	public void initInput(){
		keyInput=new AwtKeyInput(canvas);
		mouseInput=new AwtMouseInput(canvas);
	    mouseInput.initialize();
		keyInput.initialize();
		
		inputManager = new InputManager(mouseInput, keyInput, null);
		
		addKeyMapping("Quit", KeyInput.KEY_ESCAPE);
		addKeyMapping("ScriptedCamera", KeyInput.KEY_S);
		addKeyMapping("JOGLCamera", KeyInput.KEY_J);
		
		addMouseAxisMapping("MouseUp",MouseInput.AXIS_DIRECTION.AXIS_UP);
		addMouseAxisMapping("MouseDown",MouseInput.AXIS_DIRECTION.AXIS_DOWN);
		addMouseAxisMapping("MouseLeft",MouseInput.AXIS_DIRECTION.AXIS_LEFT);
		addMouseAxisMapping("MouseRight",MouseInput.AXIS_DIRECTION.AXIS_RIGHT);
	}
	
	public void destroy(){
		;
	}
	
	@Override
	public void update(GLAutoDrawable drawable){
		if(inputManager != null)
			inputManager.update();
		super.update(drawable);
	}
	
	public void start(){
		initialize();
		beginRenderingLoop();
	}
	
	/**
	 * Adds a mapping to one or more keyboard keys.
	 * For example: addKeyMapping("Quit", KeyInput.KEY_ESCAPE);
	 * @param name The name that will be used to reference this mapping
	 * @param keyCodes One or more keyCodes that will be mapped with the name parameter. KeyCodes are located in {@link KeyInput}
	 */
	public void addKeyMapping(String name, int ... keyCodes){
		for (int keyCode : keyCodes) {
			inputManager.addMapping(name, new KeyTrigger(keyCode));
		}
	    inputManager.addListener(actionListener, name);
	}
	
	/**
	 * Adds a mapping to one or more of the mouse buttons.
	 * For example: addMouseButtonMapping("MouseLeft",MouseInput.BUTTON_LEFT);
	 * @param name The name that will be used to reference this mapping
	 * @param mouseButtonNumbers One or more button numbers that will be mapped with the name parameter. MouseButtonNumbers are located in {@link MouseInput}
	 */
	public void addMouseButtonMapping(String name, int ... mouseButtonNumbers ){
		for(int mouseButtonNumber : mouseButtonNumbers){
			inputManager.addMapping(name, new MouseButtonTrigger(mouseButtonNumber));
		}
		inputManager.addListener(actionListener, name);
	}
	
	/**
	 * Adds a mapping to one of the four possible mouse direction axis.
	 * For example: addMouseAxisMapping("MouseUp",MouseInput.AXIS_DIRECTION.AXIS_UP);
	 * @param name The name that will be used to reference this mapping 
	 * @param direction The Axis Direction that will be mapped with the name parameter. Axis directions are located in {@link MouseInput}
	 */
	public void addMouseAxisMapping(String name, MouseInput.AXIS_DIRECTION direction){
		switch(direction){
			case AXIS_DOWN:
				inputManager.addMapping(name, new MouseAxisTrigger(MouseInput.AXIS_Y,true));
				break;
			case AXIS_UP:
				inputManager.addMapping(name, new MouseAxisTrigger(MouseInput.AXIS_Y,false));
				break;
			case AXIS_LEFT:
				inputManager.addMapping(name, new MouseAxisTrigger(MouseInput.AXIS_X,true));
				break;
			case AXIS_RIGHT:
				inputManager.addMapping(name, new MouseAxisTrigger(MouseInput.AXIS_X,false));
				break;
		}
		inputManager.addListener(analogListener, name);
	}

}
